package com.difsonapps.android.marker.activities;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.android.volley.Cache;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.VolleyLog;
import com.android.volley.Cache.Entry;
import com.android.volley.Request.Method;
import com.android.volley.toolbox.JsonObjectRequest;
import com.difsonapps.android.marker.AppConstant;
import com.difsonapps.android.marker.CustomRequest;
import com.difsonapps.android.marker.R;
import com.difsonapps.android.marker.R.color;
import com.difsonapps.android.marker.R.id;
import com.difsonapps.android.marker.R.layout;
import com.difsonapps.android.marker.R.menu;
import com.difsonapps.android.marker.R.string;
import com.difsonapps.android.marker.adapters.AlbumGridAdapter;
import com.difsonapps.android.marker.adapters.MarksListAdapter;
import com.difsonapps.android.marker.adapters.MarksValuesGridAdapter;
import com.difsonapps.android.marker.app.AppController;
import com.difsonapps.android.marker.beans.Album;
import com.difsonapps.android.marker.beans.Mark;
import com.difsonapps.android.marker.beans.Photo;
import com.difsonapps.android.marker.beans.Video;
import com.difsonapps.android.marker.fragments.AlbumsFragment;
import com.difsonapps.android.marker.util.MarkerUtil;

import android.os.Bundle;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.View;
import android.view.WindowManager;
import android.widget.AbsListView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AbsListView.OnScrollListener;

public class MarksActivity extends Activity {
    private static final String TAG = MarksActivity.class.getSimpleName();
    //private String URL_ALBUM = "http://10.0.2.2/putmark/public/testa/photo-marks";
    //private String URL_ALBUM = "http://10.0.2.2/putmark/public/mark/photo-marks/72/0/100";
	Photo photo; //Photo concerned by the mark
	Video video;
	ListView marksListView;
	GridView marksValuesGridView;
	ImageView markImage;
	EditText markCommentEditText;
	Button publishButton;
	Button cancelButton;
	LinearLayout loadingStatusLayout;
	
	TextView count_marks;
	TextView avg_marks;

    private MarksListAdapter marksAdapter;
    private List<Mark> marks;
	
	MarksValuesGridAdapter marksValuesGridAdapter;
	
	int currentValue = -1;
	private int offset = 0;
	private int limit = 5;
	private boolean canContinue = true;
	private boolean loading2 = false;
    String avgSym = "";
    String no_mark = "";
    String lab_mark = "";
    String lab_marks = "";
    
    int count_marks_value = 0;
    double avg_marks_value = 0;
    
    String now = "";
	
	//private int defaultValue = 5;
	//Video video;
    
    @Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		//toast("Closing...");
    	close();
		return true;
	}
    
    private void close(){
    	Intent result = new Intent();
		if(photo!=null) result.putExtra("photo", photo);
		if(video!=null) result.putExtra("video", video);
		result.putExtra("nb_marks", count_marks_value);
		result.putExtra("count_marks", count_marks_value);
		result.putExtra("avg_marks", avg_marks_value);
		setResult(RESULT_OK, result);
		finish();
    }

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_marks);
		getActionBar().setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.main_color)));

        avgSym = getResources().getString(R.string.avg_sym);
        no_mark = getResources().getString(R.string.no_mark);
        lab_mark = getResources().getString(R.string.mark);
        lab_marks = getResources().getString(R.string.marks);
        
        avg_marks = (TextView)findViewById(R.id.avg_marks);
        count_marks = (TextView)findViewById(R.id.nb_marks);
        
		marksListView = (ListView)findViewById(R.id.marksListView);
		marksValuesGridView = (GridView)findViewById(R.id.marksValuesGridView);
		
		markImage = (ImageView)findViewById(R.id.markSelectedValueImageView0);
		markCommentEditText = (EditText)findViewById(R.id.markCommentEditText);
		
		publishButton = (Button)findViewById(R.id.publishButton);
		cancelButton = (Button)findViewById(R.id.cancelButton);
		loadingStatusLayout = (LinearLayout)findViewById(R.id.loadingStatusLayout0);
		
		marks = new ArrayList<Mark>();
		 
		marksAdapter = new MarksListAdapter(this, marks);
		marksListView.setAdapter(marksAdapter);
        
		marksListView.setOnScrollListener(new EndlessScrollListener(1));
		
		marksValuesGridAdapter = new MarksValuesGridAdapter(this);
		marksValuesGridView.setAdapter(marksValuesGridAdapter);
		
		Intent i = getIntent();
		photo = i.getParcelableExtra("photo");
		video = i.getParcelableExtra("video");
		if(photo!=null){
			showMarkStats(photo.getNbMarks(), photo.getAvgMarks());
		}else if(video!=null){
			showMarkStats(video.getCountMarks(), video.getAvgMarks());
		}
		
		this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
		markImage.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				showValuesClick(v);
			}
		});
		/*publishButton.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				publish();
			}
		});
		cancelButton.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				cancel();
			}
		});*/
		
		selectMarkValue(AppConstant.DEFAULT_MARK_VALUE);
		marksValuesGridAdapter.setSelectedValue(AppConstant.DEFAULT_MARK_VALUE);
		//TODO Load the marks of the concerned photo in the listview
		loadMarks();
	}
	
	public void showMarkStats(int nb, double avg){
		avg_marks.setVisibility(nb>0?View.VISIBLE:View.GONE);
		count_marks.setText(nb==0?no_mark:(""+nb+" "+(nb==1?lab_mark:lab_marks)));
		avg_marks.setText(avgSym+" "+avg);
	}


	public void btnPublishClick(View v){
		publish();
	}
	public void btnCloseClick(View v){
		cancel();
	}
	public void showValuesClick(View v){
		if(marksValuesGridView.getVisibility()==View.GONE) marksValuesGridView.setVisibility(View.VISIBLE);
		else marksValuesGridView.setVisibility(View.GONE);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.marks, menu);
		return true;
	}
	
	public void selectMarkValue(int value){
		markImage.setImageResource(MarksValuesGridAdapter.getSelectedImage(value));
		//toast("You've selected value "+value);
	}
	
	private void toast(String text){
		Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
	}
	
	private void publish(){
		int valueSelected = marksValuesGridAdapter.getSelectedValue();
		if(valueSelected<0 || valueSelected>10) {
			toast(getResources().getString(R.string.no_value_selected));
			return;
		}
		if(photo==null && video==null) {
			toast(getResources().getString(R.string.no_item_to_mark));
			return;
		}
		String comment = markCommentEditText.getText().toString();
		Map<String, String> params = new HashMap<String, String>();
        params.put("id", ""+(photo==null?(video==null?0:video.getId()):photo.getId()));
        params.put("value", ""+valueSelected);
        params.put("comment", comment);


		showProgress();
		
		CustomRequest jsObjRequest = new CustomRequest(
				Method.POST, 
				video!=null?AppConstant.markVideoUrl:AppConstant.markPhotoUrl, 
				params,
				new Response.Listener<JSONObject>() {
					 
                    @Override
                    public void onResponse(JSONObject response) {
                    	hideProgress();
                    	//toast("Response : "+response.toString());
                    	parseJsonPostMark(response);
                    }
                },
                new Response.ErrorListener() {
 
                    @Override
                    public void onErrorResponse(VolleyError error) {
                    	hideProgress();
                    	toast("Error: " + error.getMessage());
                    }
                }
        );

       AppController.getInstance().addToRequestQueue(jsObjRequest);
	}
	private void cancel(){
		this.finish();
	}
	
	private void loadMarks(){
		Cache cache = AppController.getInstance().getRequestQueue().getCache();
    	if(!canContinue) return;
    	Map<String, String> params = new HashMap<String, String>();
        params.put("id", ""+(photo==null?(video==null?0:video.getId()):photo.getId()));
        params.put("offset", ""+offset);
        params.put("limit", ""+limit);
        String url = MarkerUtil.buildUrl(video!=null?AppConstant.listVideoMarksUrl:AppConstant.listPhotoMarksUrl, params);
    	toast(url);
        Entry entry = cache.get(url);
        if (entry != null) {
            // fetch the data from cache
            try {
                String data = new String(entry.data, "UTF-8");
                try {
                    parseJsonMarks(new JSONObject(data));
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
 
        } else {
            // making fresh volley request and getting json
            JsonObjectRequest jsonReq = new JsonObjectRequest(Method.GET,
            		url, null, new Response.Listener<JSONObject>() {
 
                        @Override
                        public void onResponse(JSONObject response) {
                            VolleyLog.d(TAG, "Response: " + response.toString());
                            if (response != null) {
                                parseJsonMarks(response);
                            }
                        }
                    }, new Response.ErrorListener() {
 
                        @Override
                        public void onErrorResponse(VolleyError error) {
                            VolleyLog.d(TAG, "Error: " + error.getMessage());
                        }
                    });
 
            // Adding request to volley request queue
            AppController.getInstance().addToRequestQueue(jsonReq);
            if(offset==0) showProgress();//au premier chargement on affiche le progress bar
            loading2=true;
        }
	}
        
        private void parseJsonMarks(JSONObject response) {
        	//toast("Response : "+response.toString());
            try {
                JSONArray feedArray = response.getJSONArray("marks");
                if(feedArray.length()==0) canContinue=false;
                
                if(response.has("count_marks")&&response.has("avg_marks")){
                	count_marks_value = response.getInt("count_marks");
                	avg_marks_value = response.getDouble("avg_marks");
                	showMarkStats(count_marks_value, avg_marks_value);
                }
                if(("".equals(now))&&response.has("now")){
                	now = response.getString("now");
                }
     
                for (int i = 0; i < feedArray.length(); i++) {
                	//toast("Loading item "+i);
                    JSONObject feedObj = (JSONObject) feedArray.get(i);
                	Mark item = Mark.parseFromJsonObject(feedObj);
                    item.setRelativeDate(MarkerUtil.getRelativeTime(item.getCreated_at(), now, this));
                	/*
                    Mark item = new Mark();
                    item.setId(feedObj.getInt("id"));
                    item.setValue(feedObj.getInt("value"));
                    item.setUserImage(feedObj.isNull("userImage") ? null : feedObj.getString("userImage"));
                    item.setUserName(feedObj.getString("userName"));
                    item.setDescription(feedObj.getString("description"));
                    item.setTimestamp(feedObj.getString("timestamp"));*/
                    if(offset==0 || offset>item.getId()) offset = item.getId();
                    marks.add(item);
                }
     
                // notify data changes to list adapater
                marksAdapter.notifyDataSetChanged();
                
                hideProgress();
                //loadingStatusLayout.setVisibility(View.GONE);
                //marksListView.setVisibility(View.VISIBLE);
            } catch (JSONException e) {
                e.printStackTrace();
            }
            loading2 = false;
        }
        
        private void parseJsonPostMark(JSONObject response) {
            try {
            	//toast(response.toString());
                if(response.has("success")){
                	String success = response.getString("success");
                	//toast(success);
                    
                    if(response.has("count_marks")&&response.has("avg_marks")){
                    	count_marks_value = response.getInt("count_marks");
                    	avg_marks_value = response.getDouble("avg_marks");
                    	showMarkStats(count_marks_value, avg_marks_value);
                    }/*else if(response.has("count_marks")&&response.has("avg_marks")){
                    	showMarkStats(response.getInt("count_marks"), response.getDouble("avg_marks"));
                    }*/
                    if(("".equals(now))&&response.has("now")){
                    	now = response.getString("now");
                    }
                	if(response.has("mark")){
                		JSONObject feedObj = response.getJSONObject("mark");
                    	Mark item = Mark.parseFromJsonObject(feedObj);
                        item.setRelativeDate(MarkerUtil.getRelativeTime(item.getCreated_at(), now, this));
                	     
                        /*Mark item = new Mark();
                        item.setId(feedObj.getInt("id"));
                        item.setValue(feedObj.getInt("value"));
                        item.setUserImage(feedObj.isNull("userImage") ? null : feedObj.getString("userImage"));
                        item.setUserName(feedObj.getString("userName"));
                        item.setDescription(feedObj.getString("description"));
                        item.setTimestamp(feedObj.getString("timestamp"));*/
                        if(offset==0 || offset>item.getId()) offset = item.getId();
                        marks.add(0, item);
                        marksAdapter.notifyDataSetChanged();
                	}
                	//int uid = response.getInt("uid");
                	//String firstname = response.getString("firstname");
                	
    				
                	//toast("User id : "+uid);
                }else if(response.has("error")){
                	String error = response.getString("error");
                	//loginErrorView.setText(error);
                	//loginErrorView.setVisibility(View.VISIBLE);
                	//TODO Show the error message in a textView and make it visible
                	toast(error);
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        

        
        class EndlessScrollListener implements OnScrollListener {

            private int visibleThreshold = 5;
            private int currentPage = 0;
            private int previousTotal = 0;
            private boolean loading = true;

            public EndlessScrollListener() {
            }
            public EndlessScrollListener(int visibleThreshold) {
                this.visibleThreshold = visibleThreshold;
            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem,
                    int visibleItemCount, int totalItemCount) {
                if (loading) {
                    if (totalItemCount > previousTotal) {
                        loading = false;
                        previousTotal = totalItemCount;
                        currentPage++;
                    }
                }
                if ((!loading) &&(!loading2) && (totalItemCount - visibleItemCount) <= (firstVisibleItem + visibleThreshold)) {
                    // I load the next page of gigs using a background task,
                    // but you can call any function here.
                	loadMarks();
                    /*new LoadGigsTask().execute(currentPage + 1);
                    loading = true;*/
                }
            }

            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
            }
        }
        
        ProgressDialog loadingProgressDialog;
        private void hideProgress(){
        	if(loadingProgressDialog!=null) loadingProgressDialog.dismiss();
        	//hideProgress();
        }
        private void showProgress(){
            loadingProgressDialog = ProgressDialog.show(this, getResources().getString(R.string.loading), getResources().getString(R.string.loading), true);
            loadingProgressDialog.setCancelable(true);
        	//showProgress(true);
        }
        private void showProgress(boolean state){
        	loadingStatusLayout.setVisibility(state?View.VISIBLE:View.GONE);
            marksListView.setVisibility(state?View.GONE:View.VISIBLE);
        }


}
